﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.Common;
using System.Linq;
using Hotel.Domain;
using Hotel.Util;


namespace HOTEL.Dao
{
    public class PhieuDatPhongDao : BaseDAO
    {
        public PHIEU_DAT_PHONG Get(string ma)
        {
            return _db.PHIEU_DAT_PHONGs.Where(p => p.MaPhieuDat.Equals(ma)).SingleOrDefault();
        }

        public List<PHIEU_DAT_PHONG> Search(string cmnd,string hoten,DateTime? TuNgay,DateTime? DenNgay,int?TinhTrangPhong)
        {
            var result = _db.PHIEU_DAT_PHONGs.Where(p=>p.MaTinhTrang.HasValue && p.MaTinhTrang.Value.Equals(TRANGTHAI_PHIEUDATPHONG.DANGDAT.GetHashCode())).AsQueryable();
            if (!String.IsNullOrEmpty(cmnd)) result = result.Where(p => p.CMND.Equals(cmnd)).AsQueryable();
            if (!String.IsNullOrEmpty(hoten)) result = result.Where(p => p.HoTen.Contains(hoten)).AsQueryable();
            if (TuNgay.HasValue) result = result.Where(p => p.NgayDen.HasValue && p.NgayDen.Value >= TuNgay.Value).AsQueryable();
            if (DenNgay.HasValue) result = result.Where(p => p.NgayDi.HasValue && p.NgayDi.Value >= DenNgay.Value).AsQueryable();
            if (TinhTrangPhong.HasValue) result = result.Where(p => p.MaTinhTrang.HasValue && p.MaTinhTrang.Value.Equals(TinhTrangPhong.Value)).AsQueryable();
            return result.ToList();
        }
        public List<PHIEU_DAT_PHONG> SearchForTraPhong(string cmnd, string hoten, DateTime? TuNgay, DateTime? DenNgay, int? TinhTrangPhong)
        {
            var result = _db.PHIEU_DAT_PHONGs.Where(p=>p.IsThanhToan==null || (p.IsThanhToan.HasValue && p.IsThanhToan.Value.Equals(false))).AsQueryable();
            if (!String.IsNullOrEmpty(cmnd)) result = result.Where(p => p.CMND.Equals(cmnd)).AsQueryable();
            if (!String.IsNullOrEmpty(hoten)) result = result.Where(p => p.HoTen.Contains(hoten)).AsQueryable();
            if (TuNgay.HasValue) result = result.Where(p => p.NgayDen.HasValue && p.NgayDen.Value >= TuNgay.Value).AsQueryable();
            if (DenNgay.HasValue) result = result.Where(p => p.NgayDi.HasValue && p.NgayDi.Value >= DenNgay.Value).AsQueryable();
            if (TinhTrangPhong.HasValue) result = result.Where(p => p.MaTinhTrang.HasValue && p.MaTinhTrang.Value.Equals(TinhTrangPhong.Value)).AsQueryable();
            return result.Where(p=>p.MaTinhTrang.HasValue && p.MaTinhTrang.Value.Equals(TRANGTHAI_PHIEUDATPHONG.DADAT.GetHashCode())).ToList();
        }
        public List<PHIEU_DAT_PHONG> GetList()
        {
            return _db.PHIEU_DAT_PHONGs.OrderBy(cv => cv.NgayDat).ToList();
        }
        public int Count()
        {
            return _db.PHIEU_DAT_PHONGs.Count();
        }

        public Message Insert(PHIEU_DAT_PHONG objUi)
        {
            Message msg;
            try
            {

                _db.Connection.Open();

                _db.PHIEU_DAT_PHONGs.InsertOnSubmit(objUi);
                _db.SubmitChanges();

                // commit

                // success message
                msg = new Message(MessageConstants.I_CREATE_SUCCEED, MessageType.Info, "phiếu đặt phòng ");
            }
            catch (Exception ex)
            {
                // rollback transaction

                msg = ExceptionHandler.HandleInsertException(ex, "phiếu đặt phòng ", objUi.HoTen);
            }
            return msg;
        }

        public Message Update(PHIEU_DAT_PHONG objUi)
        {
            Message msg;
            try
            {
                // get current object in database
                var objDb = Get(objUi.MaPhieuDat);

                if (objDb != null)
                {
                    //TODO: update all fields
                    //objDb.TenLoaiPhong = objUi.TenLoaiPhong;
                    //objDb.SoGiuong = objUi.SoGiuong;
                    _db.SubmitChanges();

                    // success message
                    msg = new Message(MessageConstants.I_UPDATE_SUCCEED, MessageType.Info, "phiếu đặt phòng ");
                }
                else
                {
                    // error message
                    msg = new Message(MessageConstants.E_OBJECT_IN_USED, MessageType.Error, "phiếu đặt phòng ", objUi.HoTen);
                }
            }
            catch (Exception ex)
            {
                msg = ExceptionHandler.HandleUpdateException(ex, "phiếu đặt phòng ", objUi.HoTen);
            }
            return msg;
        }

        public bool IsInUse(string ma)
        {
            return true;// _db.SANPHAMs.Where(p => p.PHIEU_DAT_PHONG.Equals(ma)).Count() > 0;
        }

        public Message Delete(PHIEU_DAT_PHONG objUi)
        {
            Message msg;

            try
            {
                // Get current Item in db
                var objDb = Get(objUi.MaPhieuDat);

                if (objDb == null)
                {
                    // error message
                    msg = new Message(MessageConstants.E_OBJECT_NOT_EXISTS, MessageType.Error, "phiếu đặt phòng  ", objUi.HoTen);
                    return msg;
                }


                // Set delete info
                _db.PHIEU_DAT_PHONGs.DeleteOnSubmit(objDb);
                // Submit changes to db
                _db.SubmitChanges();

                // success message
                msg = new Message(MessageConstants.I_DELETE_SUCCEED, MessageType.Info, "phiếu đặt phòng  ");
            }
            catch (Exception ex)
            {
                msg = ExceptionHandler.HandleDeleteException(ex, "phiếu đặt phòng  ");
            }

            return msg;
        }

        public Message HuyPhieuDat(PHIEU_DAT_PHONG objUi)
        {
            Message msg;

            try
            {
                // Get current Item in db
                var objDb = Get(objUi.MaPhieuDat);

                if (objDb == null)
                {
                    // error message
                    msg = new Message(MessageConstants.E_OBJECT_NOT_EXISTS, MessageType.Error, "phiếu đặt phòng  ", objUi.HoTen);
                    return msg;
                }
                objDb.MaTinhTrang = 3;
                // Submit changes to db
                _db.SubmitChanges();

                // success message
                msg = new Message(MessageConstants.I_DELETE_SUCCEED, MessageType.Info, "phiếu đặt phòng  ");
            }
            catch (Exception ex)
            {
                msg = ExceptionHandler.HandleDeleteException(ex, "phiếu đặt phòng  ");
            }

            return msg;
        }

        public Message DeleteList(List<PHIEU_DAT_PHONG> objList)
        {
            Message msg;
            DbTransaction trans = null;

            try
            {
                _db.Connection.Open();
                trans = _db.Connection.BeginTransaction();
                _db.Transaction = trans;

                var failed = 0;

                foreach (var obj in objList)
                {
                    var temp = Delete(obj);
                    if (temp != null && temp.MsgType.Equals(MessageType.Error))
                        failed++;
                }

                // commit
                trans.Commit();

                if (failed > 0)
                {
                    if (failed == objList.Count)
                        return new Message(MessageConstants.E_DELETE_FAILED_EXCEPTION, MessageType.Info, "danh sách phiếu đặt phòng ");

                    var succeed = objList.Count - failed;
                    return new Message(MessageConstants.W_DELETELIST_SUCCEED_WITH_ERRORS, MessageType.Warning,
                                       succeed, "phiếu đặt phòng ", failed, "phiếu đặt phòng ");
                }
                // success message
                msg = new Message(MessageConstants.I_DELETE_SUCCEED, MessageType.Info, objList.Count + " phiếu đặt phòng ");
            }
            catch (Exception ex)
            {
                // rollback transaction
                if (trans != null)
                    trans.Rollback();

                msg = ExceptionHandler.HandleInsertException(ex, "danh sách phiếu đặt phòng ");
            }

            return msg;
        }
        public List<TRANG_THAI_PHIEU_DAT> GetTrangThaiPhieuDat()
        {
            return _db.TRANG_THAI_PHIEU_DATs.ToList();
        }
        public List<CT_PHIEU_DAT_PHONG> GetListDetailByPhieuDat(String phieudat)
        {
            return _db.CT_PHIEU_DAT_PHONGs.Where(p => p.MaPhieuDat.Equals(phieudat)).ToList();
        }
        public CT_PHIEU_DAT_PHONG GetChiTietPhieuDat(int machitiet)
        {
            return _db.CT_PHIEU_DAT_PHONGs.Where(p => p.MaChiTietPhieuDat.Equals(machitiet)).SingleOrDefault();
        }
        public Message NhanPhong(PHIEU_THUE_PHONG objUi,CT_PHIEU_DAT_PHONG objphieudat)
        {
            Message msg;
            try
            {
                _db.Connection.Open();
                _db.PHIEU_THUE_PHONGs.InsertOnSubmit(objUi);
                var ctphieudat = _db.CT_PHIEU_DAT_PHONGs.Where(p => p.MaChiTietPhieuDat.Equals(objphieudat.MaChiTietPhieuDat)).SingleOrDefault();
                if (ctphieudat != null)
                {
                    ctphieudat.MaTinhTrang = TRANGTHAI_CHITIET_PHIEUDATPHONG.DADAT.GetHashCode();
                }
                _db.SubmitChanges();
                // cập nhật phiếu thuê là đang thue nếu tất cả chi tiết phiếu thuê =0
                var ct = Get(objUi.MaPhieuDat);
                if(ct!=null)
                {
                    if(ct.CT_PHIEU_DAT_PHONGs.Where(p=>p.MaPhieuDat.Equals(objUi.MaPhieuDat)
                                            && p.MaTinhTrang.Equals(TRANGTHAI_CHITIET_PHIEUDATPHONG.DANGCHO.GetHashCode())).Count()==0)
                    {
                        ct.MaTinhTrang=TRANGTHAI_PHIEUDATPHONG.DADAT.GetHashCode();
                        _db.SubmitChanges();
                    }
                }
                // commit
                // success message
                msg = new Message(MessageConstants.I_CREATE_SUCCEED, MessageType.Info, "phiếu thuê phòng ");
            }
            catch (Exception ex)
            {
                // rollback transaction

                msg = ExceptionHandler.HandleInsertException(ex, "phiếu thuê phòng ", objUi.TenKhachHang);
            }
            return msg;
        }
        /// <summary>
        /// Hủy chi tiết phiếu đặt phòng-> tính tiền 20 phần trăm số tiền của phòng đó.
        /// trả lại trạng thái phòng trống
        /// </summary>
        /// <param name="objUi"></param>
        /// <returns></returns>
        public Message HuyChiTietPhieuDatPhong(CT_PHIEU_DAT_PHONG objUi)
        {
            Message msg;
            try
            {
                _db.Connection.Open();
                var obj = GetChiTietPhieuDat(objUi.MaChiTietPhieuDat);
                if (obj != null)
                {
                    obj.MaTinhTrang = TRANGTHAI_CHITIET_PHIEUDATPHONG.HUY.GetHashCode();
                    obj.PhanTramTienHuy = Constans.PhanTramTienHuyPhieuDat;
                }
                var phong = _db.PHONGs.Where(p => p.MaPhong.Equals(objUi.MaPhong)).SingleOrDefault();
                if (phong != null)
                {
                    phong.MaTrangThai = TRANGTHAIPHONG.TRONG.GetHashCode();
                }
                _db.SubmitChanges();
                // cập nhật phiếu thuê là đang thue nếu tất cả chi tiết phiếu thuê =0
                var ct = Get(objUi.MaPhieuDat);
                if (ct != null)
                {
                    if (ct.CT_PHIEU_DAT_PHONGs.Where(p => p.MaPhieuDat.Equals(objUi.MaPhieuDat)
                                            && p.MaTinhTrang.Equals(TRANGTHAI_CHITIET_PHIEUDATPHONG.DANGCHO.GetHashCode())).Count() == 0)
                    {
                        ct.MaTinhTrang = TRANGTHAI_PHIEUDATPHONG.DADAT.GetHashCode();
                        _db.SubmitChanges();
                    }
                }
                // commit
                // success message
                msg = new Message(MessageConstants.I_CREATE_SUCCEED, MessageType.Info, "phiếu đăt phòng ");
            }
            catch (Exception ex)
            {
                // rollback transaction

                msg = ExceptionHandler.HandleInsertException(ex, "phiếu đăt phòng ", objUi.PHIEU_DAT_PHONG.HoTen);
            }
            return msg;
        }



        #region Phiếu thuê phòng
        public List<PHIEU_THUE_PHONG> GetListPhieuThuePhong(int? maphong, String TenPhong, int? MaHangPhong, int? MaLoaiPhong, int? MaDayPhong, int? MaTang, int? trangthai)
        {
            var result = _db.PHIEU_THUE_PHONGs.Where(p => p.PHONG.MaTrangThai.HasValue && p.PHONG.MaTrangThai.Value.Equals(TRANGTHAIPHONG.DANGSUDUNG.GetHashCode())).AsQueryable();
            if (maphong.HasValue) result = result.Where(p => p.MaPhong.Equals(maphong.Value)).AsQueryable();
            if (!String.IsNullOrEmpty(TenPhong)) result = result.Where(p => p.PHONG.TenPhong.Contains(TenPhong)).AsQueryable();
            if (MaHangPhong.HasValue) result = result.Where(p => p.PHONG.MaHangPhong.Equals(MaHangPhong.Value)).AsQueryable();
            if (MaDayPhong.HasValue) result = result.Where(p => p.PHONG.MaDay.Equals(MaDayPhong.Value)).AsQueryable();
            if (MaLoaiPhong.HasValue) result = result.Where(p => p.PHONG.MaLoaiPhong.Equals(MaLoaiPhong.Value)).AsQueryable();
            if (MaTang.HasValue) result = result.Where(p => p.PHONG.MaTang.Equals(MaTang.Value)).AsQueryable();
            if (trangthai.HasValue) result = result.Where(p => p.PHONG.MaTrangThai.Equals(trangthai.Value)).AsQueryable();
            return result.OrderBy(p => p.PHONG.MaTrangThai).ThenBy(p => p.PHONG.MaTang).ThenBy(p => p.PHONG.MaLoaiPhong).ToList();
        }
        public PHIEU_THUE_PHONG GetPhieuThuePhong(int maphieu)
        {
            return _db.PHIEU_THUE_PHONGs.Where(p => p.MaPhieuThue.Equals(maphieu)).SingleOrDefault();
        }
        public SU_DUNG_DICH_VU GetSuDungDichVu(int maphieu)
        {
            return _db.SU_DUNG_DICH_VUs.Where(p => p.MaPhieuSuDungDichVu.Equals(maphieu)).SingleOrDefault();
        }

        public List<SU_DUNG_DICH_VU> GetSuDungDichVuListFromPhieuThue(int maphieuthue)
        {
            return _db.SU_DUNG_DICH_VUs.Where(p => p.MaPhieuThue.Equals(maphieuthue)).OrderBy(p => p.NgaySuDung).ToList();
        }
        public Message ThemDichVu(SU_DUNG_DICH_VU objUi)
        {
            Message msg;
            try
            {
                _db.Connection.Open();
                _db.SU_DUNG_DICH_VUs.InsertOnSubmit(objUi);
                _db.SubmitChanges();
                // commit
                // success message
                msg = new Message(MessageConstants.I_CREATE_SUCCEED, MessageType.Info, "dịch vụ ");
            }
            catch (Exception ex)
            {
                // rollback transaction

                msg = ExceptionHandler.HandleInsertException(ex, "dịch vụ ", objUi.PHIEU_THUE_PHONG.TenKhachHang);
            }
            return msg;
        }
        public Message XoaDichVu(SU_DUNG_DICH_VU objUi)
        {
            Message msg;
            try
            {
                _db.Connection.Open();
                var obj = GetSuDungDichVu(objUi.MaPhieuSuDungDichVu);
                if (obj == null)
                {
                    msg = new Message(MessageConstants.E_OBJECT_NOT_EXISTS, MessageType.Error, "dịch vụ  ", objUi.DICH_VU.TenDV);
                    return msg;
                }
                _db.SU_DUNG_DICH_VUs.DeleteOnSubmit(objUi);
                _db.SubmitChanges();
                // commit
                // success message
                msg = new Message(MessageConstants.I_CREATE_SUCCEED, MessageType.Info, "dịch vụ ");
            }
            catch (Exception ex)
            {
                // rollback transaction

                msg = ExceptionHandler.HandleInsertException(ex, "dịch vụ ", objUi.PHIEU_THUE_PHONG.TenKhachHang);
            }
            return msg;
        }
        #endregion


        #region Tính Tiền
        public Message TinhTien(ref HOA_DON  hoadonref, PHIEU_DAT_PHONG obj,String TenKhachHang,String DiaChi,String MST,int manv,DateTime NgayDen,DateTime NgayTra)
        {
            Message msg;
            DbTransaction trans = null;

            try
            {
                _db.Connection.Open();
                trans = _db.Connection.BeginTransaction();
                _db.Transaction = trans;
                var hoadon = new HOA_DON
                {
                    MaHoaDon=DateTime.Now.ToString("yyMMddhhss"),
                    MaNV=manv,
                    MaPhieuDat=obj.MaPhieuDat,
                    NgayLap=DateTime.Now,
                    NgayDen=NgayDen,
                    NgayDi=NgayTra,
                    TenKhachHang=TenKhachHang,
                    DiaChi=DiaChi,
                    MaSoThue=MST
                };
                var listChiTietHoaDon = new List<CHI_TIET_HOA_DON>();
                // TÍNH TIẾN PHÒNG
                var phieuthuephonglist = _db.PHIEU_THUE_PHONGs.Where(p => p.MaPhieuDat.Equals(obj.MaPhieuDat)).ToList();
                decimal tongtien = 0;
                foreach (var item in phieuthuephonglist)
                {
                    // TÍNH TIỀN DỊCH VỤ
                    var dichvulist=_db.SU_DUNG_DICH_VUs.Where(p=>p.MaPhieuThue.Equals(item.MaPhieuThue)).ToList();
                    foreach(var dv in dichvulist){
                        var cthd = new CHI_TIET_HOA_DON
                        {
                            MaHoaDon=hoadon.MaHoaDon,
                            TenDichVu=String.Format("Phí sử dụng {0}",dv.DICH_VU.TenDV) ,
                            MaDichVu=item.MaPhieuDat.ToString(),
                            DonGia=dv.DonGia,
                            SoLuong=dv.SoLuong,
                            LoaiDichVu=LOAIDICHVU.DV.ToString()
                        };
                        tongtien += cthd.SoLuong.Value * cthd.DonGia.Value;
                        listChiTietHoaDon.Add(cthd);
                    }
                    var phong = _db.PHONGs.Where(p => p.MaPhong.Equals(item.MaPhong)).SingleOrDefault();
                    if (phong != null)
                    {
                        phong.MaTrangThai = TRANGTHAIPHONG.TRONG.GetHashCode();
                        _db.SubmitChanges();
                    }
                    var cthoadon = new CHI_TIET_HOA_DON
                    {
                        MaHoaDon=hoadon.MaHoaDon,
                        TenDichVu="Tiền thuê phòng",
                        MaDichVu = item.MaPhieuDat.ToString(),
                        DonGia=item.DonGia,
                        SoLuong=1,
                        LoaiDichVu=LOAIDICHVU.TP.ToString()
                    };
                    tongtien += cthoadon.SoLuong.Value * cthoadon.DonGia.Value;
                    listChiTietHoaDon.Add(cthoadon);
                }
                var phieudatphonghuy = _db.CT_PHIEU_DAT_PHONGs.Where(p => p.MaPhieuDat.Equals(obj.MaPhieuDat)
                                                && p.MaTinhTrang.HasValue&& p.MaTinhTrang.Value.Equals(TRANGTHAI_CHITIET_PHIEUDATPHONG.HUY.GetHashCode())).ToList();
                foreach(var item in phieudatphonghuy){
                    var cthoadon = new CHI_TIET_HOA_DON
                    {
                        MaHoaDon = hoadon.MaHoaDon,
                        TenDichVu = "Tiền hủy phiếu thuê phòng",
                        MaDichVu = item.MaPhieuDat.ToString(),
                        DonGia = item.DonGia.Value*(decimal)(item.PhanTramTienHuy.Value*1.0/100),
                        SoLuong = 1,
                        LoaiDichVu = LOAIDICHVU.TPH.ToString()
                    };
                    tongtien += cthoadon.SoLuong.Value * cthoadon.DonGia.Value;
                    listChiTietHoaDon.Add(cthoadon);
                }
                _db.HOA_DONs.InsertOnSubmit(hoadon);
                var phieudatphong = Get(obj.MaPhieuDat);
                phieudatphong.IsThanhToan = true;
                hoadonref = hoadon;
                _db.SubmitChanges();
                _db.CHI_TIET_HOA_DONs.InsertAllOnSubmit(listChiTietHoaDon);
                _db.SubmitChanges();
                trans.Commit();
                msg = new Message(MessageConstants.I_CREATE_SUCCEED, MessageType.Info, "thanh toán ");
            }
            catch (Exception ex)
            {
                // rollback transaction
                if (trans != null)
                    trans.Rollback();
                msg = ExceptionHandler.HandleInsertException(ex, "thanh toán ", obj.MaPhieuDat.ToString());
            }
            return msg;
        }
        #endregion
    }
}

